//
//  FolderCell.m
//  My Dream Slapper
//
//  Created by Jason Harris on 8/27/06.
//  Copyright (c) 2006, Jason Harris and Geekspiff
//  All rights reserved.
//  
//  Redistribution and use in source and binary forms, with or without modification, are permitted provided
//  that the following conditions are met:
//  
//  Redistributions of source code must retain the above copyright notice, this list of conditions and the
//  following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list
//  of conditions and the following disclaimer in the documentation and/or other materials provided with the
//  distribution. Neither the name of Jason Harris, Geekspiff, nor the names of its contributors may be used
//  to endorse or promote products derived from this software without specific prior written permission.
//  
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
//  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
//  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
//  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
//  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
//  POSSIBILITY OF SUCH DAMAGE.
//

#import "FolderCell.h"
#import "NSAttributedString_additions.h"

// --- Constants --- //
static NSSize kMinimumCellSize = {90.0, 45.0};
static NSPoint kIconOrigin = {6.0, 6.0};
static NSSize kIconSize = {32.0, 32.0};
static NSPoint kTitleOrigin = {6.0, 5.0};
static float kTitleRightMargin = 0.0;
static float kTitleHeight = 17.0;
static NSPoint kSmallPrintOrigin = {3.0, 22.0};
static float kSmallPrintRightMargin = 8.0;
static float kSmallPrintHeight = 15.0;


// --- Global Variables --- //
static NSMutableDictionary *gTitleAttributes = nil;
static NSMutableDictionary *gSmallPrintAttributes = nil;


@implementation FolderCell

#pragma mark Text


+ (NSMutableDictionary *)titleAttributes
{
	if ( ! gTitleAttributes )
	{
		NSFont *font = [NSFont controlContentFontOfSize: 0];
		gTitleAttributes = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
			font,			NSFontAttributeName, 
			nil,			nil];
	}
	return gTitleAttributes;
}


+ (NSMutableDictionary *)smallPrintAttributes
{
	if ( ! gSmallPrintAttributes )
	{
		NSFont *font = [NSFont labelFontOfSize: 9];
		gSmallPrintAttributes = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
			font,			NSFontAttributeName, 
			nil,			nil];
	}
	return gSmallPrintAttributes;
}


- (NSColor *)textColorInView: (NSView *)controlView
{
	if ( [self isHighlighted] )
	{
		return [NSColor alternateSelectedControlTextColor];
	}
	
	return [NSColor controlTextColor];
}


#pragma mark Setting and Getting Content

- (void)setObjectValue: (id)object
{  _objectValue = object;  }


#pragma mark Layout Support
/* All geometry assumes a flipped co-ordinate system */

- (NSSize)cellSize
{  return kMinimumCellSize;  }


- (NSRect)drawingRectForBounds:(NSRect)theRect
{
	return theRect;
}


- (NSRect)iconRectForBounds: (NSRect)cellFrame
{
	return NSMakeRect( NSMinX( cellFrame ) + kIconOrigin.x, 
					   NSMinY( cellFrame ) + kIconOrigin.y, 
					   kIconSize.width, 
					   kIconSize.height );
}


- (NSRect)smallPrintRectForBounds: (NSRect)cellFrame
{
	float leftOrigin = NSMinX( [self titleRectForBounds: cellFrame] );
	float width = NSWidth( cellFrame ) - leftOrigin - kSmallPrintRightMargin;
	return NSMakeRect( leftOrigin, 
					   NSMinY( cellFrame ) + kSmallPrintOrigin.y, 
					   width, 
					   kSmallPrintHeight );
}


- (NSRect)titleRectForBounds: (NSRect)cellFrame
{
	float leftOrigin = NSMaxX( [self iconRectForBounds: cellFrame] ) + kTitleOrigin.x;
	float width = NSWidth( cellFrame ) - leftOrigin - kTitleRightMargin;
	NSRect titleRect = NSMakeRect( leftOrigin, 
								   NSMinY( cellFrame ) + kTitleOrigin.y, 
								   width, 
								   kTitleHeight );
	
	static BOOL inRecursion = NO;
	if ( ! _drawingSmallPrint && !inRecursion )
	{
		inRecursion = YES;
		@try
		{
			NSRect smallPrintRect = [self smallPrintRectForBounds: cellFrame];
			NSRect unionRect = NSUnionRect( titleRect, smallPrintRect );
			float midY = NSMidY( unionRect );
			float halfTitle = NSHeight( titleRect ) / 2.0;
			float newY = midY - halfTitle - 4.0;
			titleRect.origin.y = newY;
			inRecursion = NO;
		} @finally {
			inRecursion = NO;
		}
	}
	
	return titleRect;
}


#pragma mark Drawing


- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
	[self highlight: [self isHighlighted] withFrame: cellFrame inView: controlView];
	cellFrame = [self drawingRectForBounds: cellFrame];
	[self drawInteriorWithFrame: cellFrame inView: controlView];
}


- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
	[self drawIconWithFrame: cellFrame inView: controlView];
	[self drawSmallPrintWithFrame: cellFrame inView: controlView];
	[self drawTitleWithFrame: cellFrame inView: controlView];
}


- (void)drawIconWithFrame: (NSRect)cellFrame inView:(NSView *)controlView
{
	NSImage *icon = [_objectValue valueForKey: @"icon"];
	if ( icon )
	{
		BOOL wasFlipped = [icon isFlipped];
		@try
		{
			[icon setFlipped: YES];
			cellFrame = [self iconRectForBounds: cellFrame];
			[icon drawInRect: cellFrame fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 1.0];
			[icon setFlipped: wasFlipped];
		} @finally
		{
			[icon setFlipped: wasFlipped];
		}
	}
}


- (void)drawSmallPrintWithFrame: (NSRect)cellFrame inView:(NSView *)controlView
{
	_drawingSmallPrint = NO;
	NSSet *entries = [_objectValue valueForKey: @"entries"];
	int entryCount = [entries count];
	if ( entryCount )
	{
		_drawingSmallPrint = YES;
		NSString *entryString = [NSString stringWithFormat: @"%d", entryCount];
		cellFrame = [self smallPrintRectForBounds: cellFrame];
		NSMutableDictionary *attributes = [[self class] smallPrintAttributes];
		[attributes setObject: [self textColorInView: controlView] forKey: NSForegroundColorAttributeName];
		NSAttributedString *attrString = [[[NSAttributedString alloc] initWithString: entryString attributes: attributes] autorelease];
		attrString = [attrString attributedStringForWidth: NSWidth( cellFrame )];
		[attrString drawInRect: cellFrame];
	}
}


- (void)drawTitleWithFrame: (NSRect)cellFrame inView:(NSView *)controlView
{
	NSString *title = [_objectValue valueForKey: @"name"];
	if ( title )
	{
		cellFrame = [self titleRectForBounds: cellFrame];
		NSMutableDictionary *attributes = [[self class] titleAttributes];
		[attributes setObject: [self textColorInView: controlView] forKey: NSForegroundColorAttributeName];
		[title drawInRect: cellFrame withAttributes: attributes];
	}
}

@end
